import React, { useRef, useEffect, useMemo } from 'react';
import { useFrame, useThree } from '@react-three/fiber';
import * as THREE from 'three';

interface ParticleBurstProps {
  position: [number, number, number];
  count?: number; // 粒子数量
  speed?: number; // 粒子速度
  duration?: number; // 动画持续时间 (秒)
  color?: string; // 粒子颜色
  onAnimationEnd: () => void; // 动画结束回调
}

export function ParticleBurst({
  position,
  count = 50,
  speed = 1,
  duration = 1,
  color = '#FFFF00', // 黄色闪光
  onAnimationEnd,
}: ParticleBurstProps) {
  const meshRef = useRef<THREE.Points>(null);

  // 在组件顶层调用 useThree 获取 clock
  const { clock } = useThree();

  // 使用 useMemo 创建粒子几何体和材质，避免重复计算
  const [geometry, material] = useMemo(() => {
    const geo = new THREE.BufferGeometry();
    const pos = new Float32Array(count * 3); // 存储粒子位置
    const vel = new Float32Array(count * 3); // 存储粒子速度

    for (let i = 0; i < count; i++) {
      // 随机生成粒子初始位置 (在指定位置附近)
      pos[i * 3] = position[0] + (Math.random() - 0.5) * 0.5;
      pos[i * 3 + 1] = position[1] + (Math.random() - 0.5) * 0.5;
      pos[i * 3 + 2] = position[2] + (Math.random() - 0.5) * 0.5;

      // 随机生成粒子初始速度 (向外扩散)
      const direction = new THREE.Vector3(
        Math.random() - 0.5,
        Math.random() - 0.5,
        Math.random() - 0.5
      ).normalize();
      vel[i * 3] = direction.x * speed * (0.5 + Math.random());
      vel[i * 3 + 1] = direction.y * speed * (0.5 + Math.random());
      vel[i * 3 + 2] = direction.z * speed * (0.5 + Math.random());
    }

    geo.setAttribute('position', new THREE.BufferAttribute(pos, 3));
    geo.setAttribute('velocity', new THREE.BufferAttribute(vel, 3));

    const mat = new THREE.PointsMaterial({
      color: color,
      size: 0.2, // 粒子大小
      transparent: true,
      blending: THREE.AdditiveBlending, // 叠加混合模式，产生发光效果
      depthWrite: false, // 不写入深度缓冲区，避免粒子之间的遮挡问题
    });

    return [geo, mat];
  }, [count, speed, color, position]); // 依赖项

  // 使用 useFrame 更新粒子位置和透明度
  useFrame((state, delta) => {
    if (!meshRef.current) return;

    const positions = meshRef.current.geometry.attributes.position.array as Float32Array;
    const velocities = meshRef.current.geometry.attributes.velocity.array as Float32Array;
    const material = meshRef.current.material as THREE.PointsMaterial;

    // 更新粒子位置
    for (let i = 0; i < count; i++) {
      positions[i * 3] += velocities[i * 3] * delta;
      positions[i * 3 + 1] += velocities[i * 3 + 1] * delta;
      positions[i * 3 + 2] += velocities[i * 3 + 2] * delta;
    }

    meshRef.current.geometry.attributes.position.needsUpdate = true; // 标记位置需要更新

    // 更新粒子透明度 (随时间消逝)
    const elapsed = state.clock.getElapsedTime();
    const progress = (elapsed - (meshRef.current.userData.startTime || elapsed)) / duration;
    material.opacity = Math.max(0, 1 - progress); // 透明度从 1 渐变到 0

    // 动画结束时移除组件
    if (progress >= 1) {
        onAnimationEnd();
    }
  });

  // 记录动画开始时间
  useEffect(() => {
      if(meshRef.current) {
          // 使用从 useThree 获取的 clock
          meshRef.current.userData.startTime = clock.getElapsedTime();
      }
  }, [clock]); // 依赖 clock

  return <points ref={meshRef} geometry={geometry} material={material} />;
} 